package linuxbox;

import java.io.*;
import java.text.*;
import java.util.*;

import org.apache.log4j.*;
import org.jdom.*;
import org.jdom.input.*;

import org.apache.commons.digester.*;
import org.apache.commons.digester.xmlrules.*;

import linuxbox.exception.*;
import linuxbox.util.*;

import com.thebox.config.*;

public class BoxStatic {
    /***********************************

     managed by 6mao

    *************************************/
    public static boolean isPostgreSQL = true;

    public static String SHORT_DATE_FORMAT = new String("MM/dd/yyyy");
    public static String VERYLONG_DATE_FORMAT = new String("EEEE MMMMM d,yyyy");
    public static String LONG_DATE_FORMAT = new String("MMMMM d,yyyy");
    public static String SHORT_TIME_FORMAT = new String("hh:mm a");
    public static String SHORT_HOUR_FORMAT = new String("h a");
    public static String VERYSHORT_HOUR_FORMAT = new String("H");
    public static String MONTH_YEAR_FORMAT = new String("MMMM yyyy");
    public static String SHORT_DATETIME_FORMAT = new String("MM/dd/yy hh:mm a");

    //Since this is shared by all the application, call applyPatten first
    //then call format to get what you want
    public static SimpleDateFormat dateTimeFormatter = new SimpleDateFormat(LONG_DATE_FORMAT, Locale.US);

    public static DateFormatSymbols dateTimeSymbols = dateTimeFormatter.getDateFormatSymbols();

    public static String[] shortWeekSymbols = dateTimeSymbols.getShortWeekdays();
    public static String[] weekSymbols = dateTimeSymbols.getWeekdays();
    public static String[] shortMonthSymbols = dateTimeSymbols.getShortMonths();
    public static String[] monthSymbols = dateTimeSymbols.getMonths();

    /***********************************

     managed by zhangjw

    *************************************/

    // used by system init
    public static String MAIN_CONFIG_FILE = "main";
    //public static String HOME_DIR_PARAM = "HomeDirectory";

    //public static final String POSTGRES_TIMESTAMP_FORMAT = "yyyy-MM-dd HH:mm:sszzz";
    public static String POSTGRES_DATE_FORMAT = "yyyy-MM-dd";
    public static String POSTGRES_TIME_FORMAT = "HH:mm:ss";
    public static String NORMAL_DATETIME_FORMAT = "yyyy.MM.dd 'at' hh:mm:ss";

    public static String BOX_SESSION = "BoxSession";
    public static String EXCEPTION = "EXCEPTION";
    public static String DOWNLOAD_OBJECT = "DownloadObject";

    public static String HOME_DIR = null;
    public static String DOWNLOAD_FILE_DIR = null;
    public static boolean PRINT_STACK_TRACE = true;

    // function object instances
    public static ConnectionPool cPool = null;
    public static Logger logger = Logger.getRootLogger();
    //public static XMLProperties XmlProp = null;

    // deprecated, use mainConfig instead
    //public static ModuleControl moduleControl = null;

    public static MainConfig mainConfig = null;
    public static ExceptionHelper excHelper = null;
    public static BoxFormat formater = null;
    public static Timer timer = new Timer();

    public static String noUserJSP = null;
    public static String errorJSP = null;
    public static String timeoutJSP = null;
    public static String accessRightErrorJSP = null;
    public static String defaultLang = "en";
    public static String servletPath = "/BoxServlet";
    public static String webInfPath = "WEB-INF";
    public static String configPath = "WEB-INF";
    public static String contextName = null;
    public static String jspDir = null;
    public static String servletDir = null;
    public static String imageDir = null;
    public static String cssDir = null;

    // Database init paramters
    public static String dbUrl = null;
    public static String dbDriver = null;
    public static String username = null;
    public static String password = "";

    public static int initSize = 4;
    public static int maxSize = 20;
    public static long expireTime = -1;

    // Taglib common constants
    public static String DISPLAY_TYPE_LIST = "LIST";
    public static String DISPLAY_TYPE_TABLE = "TABLE";

    // User admin related taglib constants
    public static String USER_TYPE_ALL = "ALL";
    public static String USER_TYPE_ONLINE = "ONLINE";
    public static String USER_TYPE_BUSY = "BUSY";
    public static String USER_TYPE_AWAY = "AWAY";
    public static String USER_TYPE_CHECKOUT = "CHECKOUT";

    public static String PRIVILEGE_TYPE_ADMIN = "ADMIN";
    public static String PRIVILEGE_TYPE_USER = "USER";

    public static boolean serviceSwitch = true;
    public static String SERVICE_OFF_PAGE = "ServiceOff.html";

    // init logger
    static {
        logger.setLevel(Level.ERROR);
        logger.addAppender(new ConsoleAppender(new PatternLayout("%5p (%F:%L) - %m%n")));
    }

    public static void init() throws Exception {
        String configFile = BoxStatic.HOME_DIR + BoxStatic.webInfPath +
            File.separator + "BoxConfig.xml";
        //      configFile = "d:/tools/tomcat/webapps/netobox/WEB-INF/BoxConfig.xml";

        SAXBuilder builder = new SAXBuilder(false);
        Document doc = builder.build(new FileInputStream(configFile));
        Element root = doc.getRootElement();

        Element DbConfig = root.getChild("DatabaseConfig");
        String db = DbConfig.getChildText("Database");
        if ("postgresql".equalsIgnoreCase(db)) {
            isPostgreSQL = true;
        } else {
            isPostgreSQL = false;
        }
        Element DbFormat = DbConfig.getChild("DbFormat");
        List formats = DbFormat.getChildren("Format");
        for (Iterator it = formats.iterator(); it.hasNext(); ) {
            Element f = (Element)it.next();
            String name = f.getAttributeValue("name");
            String value = f.getAttributeValue("value");
            if ("SHORT_DATE".equalsIgnoreCase(name)) {
                SHORT_DATE_FORMAT = value;
            } else if ("VERYLONG_DATE".equalsIgnoreCase(name)) {
                VERYLONG_DATE_FORMAT = value;
            } else if ("LONG_DATE".equalsIgnoreCase(name)) {
                LONG_DATE_FORMAT = value;
            } else if ("SHORT_TIME".equalsIgnoreCase(name)) {
                SHORT_TIME_FORMAT = value;
            } else if ("SHORT_HOUR".equalsIgnoreCase(name)) {
                SHORT_HOUR_FORMAT = value;
            } else if ("VERYSHORT_HOUR".equalsIgnoreCase(name)) {
                VERYSHORT_HOUR_FORMAT = value;
            } else if ("MONTH_YEAR".equalsIgnoreCase(name)) {
                MONTH_YEAR_FORMAT = value;
            } else if ("POSTGRES_DATE".equalsIgnoreCase(name)) {
                POSTGRES_DATE_FORMAT = value;
            } else if ("POSTGRES_TIME".equalsIgnoreCase(name)) {
                POSTGRES_TIME_FORMAT = value;
            } else if ("NORMAL_DATETIME".equalsIgnoreCase(name)) {
                NORMAL_DATETIME_FORMAT = value;
            }
        }

        Element ConnPool = DbConfig.getChild("ConnPool");
        List params = ConnPool.getChildren("Param");
        for (Iterator it = params.iterator(); it.hasNext(); ) {
            Element p = (Element)it.next();
            String name = p.getAttributeValue("name");
            String value = p.getAttributeValue("value");
            if ("initSize".equalsIgnoreCase(name)) {
                initSize = Integer.parseInt(value);
            } else if ("maxSize".equalsIgnoreCase(name)) {
                maxSize = Integer.parseInt(value);
            } else if ("expireTime".equalsIgnoreCase(name)) {
                expireTime = Integer.parseInt(value);
            }
        }

        Element SysConfig = root.getChild("SystemConfig");
        servletPath = SysConfig.getChildText("ServletPath");
        serviceSwitch = "true".equalsIgnoreCase(SysConfig.getChildText("ServiceSwitch"));
        SERVICE_OFF_PAGE = SysConfig.getChildText("ServiceOffPage");

        Element BoxConstant = root.getChild("BoxConstant");
        List constants = BoxConstant.getChildren("Constant");
        for (Iterator it = constants.iterator(); it.hasNext(); ) {
            Element c = (Element)it.next();
            String name = c.getAttributeValue("name");
            String value = c.getAttributeValue("value");
            if ("DISPLAY_TYPE_LIST".equalsIgnoreCase(name)) {
                DISPLAY_TYPE_LIST = value;
            } else if ("DISPLAY_TYPE_TABLE".equalsIgnoreCase(name)) {
                DISPLAY_TYPE_TABLE = value;
            } else if ("PRIVILEGE_TYPE_ADMIN".equalsIgnoreCase(name)) {
                PRIVILEGE_TYPE_ADMIN = value;
            } else if ("PRIVILEGE_TYPE_USER".equalsIgnoreCase(name)) {
                PRIVILEGE_TYPE_USER = value;
            } else if ("USER_TYPE_ALL".equalsIgnoreCase(name)) {
                USER_TYPE_ALL = value;
            } else if ("USER_TYPE_ONLINE".equalsIgnoreCase(name)) {
                USER_TYPE_ONLINE = value;
            } else if ("USER_TYPE_BUSY".equalsIgnoreCase(name)) {
                USER_TYPE_BUSY = value;
            } else if ("USER_TYPE_AWAY".equalsIgnoreCase(name)) {
                USER_TYPE_AWAY = value;
            } else if ("USER_TYPE_CHECKOUT".equalsIgnoreCase(name)) {
                USER_TYPE_CHECKOUT = value;
            } else if ("BOX_SESSION".equalsIgnoreCase(name)) {
                BOX_SESSION = value;
            } else if ("EXCEPTION".equalsIgnoreCase(name)) {
                EXCEPTION = value;
            } else if ("DOWNLOAD_OBJECT".equalsIgnoreCase(name)) {
                DOWNLOAD_OBJECT = value;
            }
        }
    }

    public static void zinit() throws Exception {
        String configFile = BoxStatic.HOME_DIR + BoxStatic.webInfPath +
            File.separator + "BoxConfig.xml";
        // configFile = "d:/tools/tomcat/webapps/netobox/WEB-INF/BoxConfig.xml";
        String ruleFile = BoxStatic.HOME_DIR + BoxStatic.webInfPath +
            File.separator + "/digester/BoxConfigRule.xml";
        // configFile = "d:/tools/tomcat/webapps/netobox/WEB-INF/BoxConfig.xml";

        File input = new File(configFile);
        File rules = new File(ruleFile);

        //debug("input path: " + input.getPath());
        String inputPath = input.getAbsoluteFile().getParent();
        //debug("input path parent: " + inputPath);
        String rulesPath = rules.getAbsoluteFile().getParent();
        //debug("rules path parent: " + rulesPath);

        Digester digester = DigesterLoader.createDigester(rules.toURI().toURL());
        TheBoxConfig bc = (TheBoxConfig)digester.parse(input);
        //debug(bc.toString());

        String db = bc.getDatabase();
        if ("postgresql".equalsIgnoreCase(db)) {
            isPostgreSQL = true;
        } else {
            isPostgreSQL = false;
        }

        Map formats = bc.getDbFormat();
        for (Iterator it = formats.entrySet().iterator(); it.hasNext(); ) {
            Map.Entry en = (Map.Entry)it.next();
            String name = (String)en.getKey();
            String value = (String)en.getValue();

            if ("SHORT_DATE".equalsIgnoreCase(name)) {
                SHORT_DATE_FORMAT = value;
            } else if ("VERYLONG_DATE".equalsIgnoreCase(name)) {
                VERYLONG_DATE_FORMAT = value;
            } else if ("LONG_DATE".equalsIgnoreCase(name)) {
                LONG_DATE_FORMAT = value;
            } else if ("SHORT_TIME".equalsIgnoreCase(name)) {
                SHORT_TIME_FORMAT = value;
            } else if ("SHORT_HOUR".equalsIgnoreCase(name)) {
                SHORT_HOUR_FORMAT = value;
            } else if ("VERYSHORT_HOUR".equalsIgnoreCase(name)) {
                VERYSHORT_HOUR_FORMAT = value;
            } else if ("MONTH_YEAR".equalsIgnoreCase(name)) {
                MONTH_YEAR_FORMAT = value;
            } else if ("POSTGRES_DATE".equalsIgnoreCase(name)) {
                POSTGRES_DATE_FORMAT = value;
            } else if ("POSTGRES_TIME".equalsIgnoreCase(name)) {
                POSTGRES_TIME_FORMAT = value;
            } else if ("NORMAL_DATETIME".equalsIgnoreCase(name)) {
                NORMAL_DATETIME_FORMAT = value;
            }
        }

        Map params = bc.getConnPoolParam();
        for (Iterator it = params.entrySet().iterator(); it.hasNext(); ) {
            Map.Entry p = (Map.Entry)it.next();
            String name = (String)p.getKey();
            String value = (String)p.getValue();
            if ("initSize".equalsIgnoreCase(name)) {
                initSize = Integer.parseInt(value);
            } else if ("maxSize".equalsIgnoreCase(name)) {
                maxSize = Integer.parseInt(value);
            } else if ("expireTime".equalsIgnoreCase(name)) {
                expireTime = Integer.parseInt(value);
            }
        }

        servletPath = bc.getServletPath();
        serviceSwitch = "true".equalsIgnoreCase(bc.getServiceSwitch());
        SERVICE_OFF_PAGE = bc.getServiceOffPage();

        Map constants = bc.getBoxConstant();
        for (Iterator it = constants.entrySet().iterator(); it.hasNext(); ) {
            Map.Entry c = (Map.Entry)it.next();
            String name = (String)c.getKey();
            String value = (String)c.getValue();
            if ("DISPLAY_TYPE_LIST".equalsIgnoreCase(name)) {
                DISPLAY_TYPE_LIST = value;
            } else if ("DISPLAY_TYPE_TABLE".equalsIgnoreCase(name)) {
                DISPLAY_TYPE_TABLE = value;
            } else if ("PRIVILEGE_TYPE_ADMIN".equalsIgnoreCase(name)) {
                PRIVILEGE_TYPE_ADMIN = value;
            } else if ("PRIVILEGE_TYPE_USER".equalsIgnoreCase(name)) {
                PRIVILEGE_TYPE_USER = value;
            } else if ("USER_TYPE_ALL".equalsIgnoreCase(name)) {
                USER_TYPE_ALL = value;
            } else if ("USER_TYPE_ONLINE".equalsIgnoreCase(name)) {
                USER_TYPE_ONLINE = value;
            } else if ("USER_TYPE_BUSY".equalsIgnoreCase(name)) {
                USER_TYPE_BUSY = value;
            } else if ("USER_TYPE_AWAY".equalsIgnoreCase(name)) {
                USER_TYPE_AWAY = value;
            } else if ("USER_TYPE_CHECKOUT".equalsIgnoreCase(name)) {
                USER_TYPE_CHECKOUT = value;
            } else if ("BOX_SESSION".equalsIgnoreCase(name)) {
                BOX_SESSION = value;
            } else if ("EXCEPTION".equalsIgnoreCase(name)) {
                EXCEPTION = value;
            } else if ("DOWNLOAD_OBJECT".equalsIgnoreCase(name)) {
                DOWNLOAD_OBJECT = value;
            }
        }
    }

    public static void cleanUp() {
        try {
            if (cPool != null) cPool.clearConnPool();
            LogManager.shutdown();
            logger = null;
            //moduleControl = null;
            mainConfig = null;
            excHelper = null;
            formater = null;
            timer = null;
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void debug(Object obj) {
        System.out.println("From BoxStatic: " + obj);
    }

    public static void main(String[] args) {
        try {
            init();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
